package com.hvisions.server.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hvisions.common.MyUaNode;
import com.hvisions.common.Tree;
import com.hvisions.common.enums.EquipmentTypeEnum;
import com.hvisions.config.OpcUaConfig;
import com.hvisions.server.mapper.TbEquipmentMapper;
import com.hvisions.server.mapper.TbOpcPointMapper;
import com.hvisions.server.model.TbEquipment;
import com.hvisions.server.model.TbOpcPoint;
import com.hvisions.server.service.ITbEquipmentService;
import com.hvisions.server.service.ITbOpcPointService;
import org.eclipse.milo.opcua.sdk.client.model.nodes.objects.FolderTypeNode;
import org.eclipse.milo.opcua.sdk.client.model.nodes.variables.BaseVariableTypeNode;
import org.eclipse.milo.opcua.sdk.client.nodes.UaNode;
import org.eclipse.milo.opcua.stack.core.AttributeId;
import org.eclipse.milo.opcua.stack.core.types.builtin.NodeId;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author kzyang
 * @since 2023-02-06
 */
@Service
public class TbEquipmentServiceImpl extends ServiceImpl<TbEquipmentMapper, TbEquipment> implements ITbEquipmentService {

    @Override
    public Boolean asyncEquipment(MyUaNode uaNode) throws Exception {
        String parentName = null;
        if(ObjectUtil.isNull(uaNode.getId())){
            uaNode = null;
        }else {
            parentName = getParentName(uaNode.getId(), "");
            uaNode.setNodeId(new NodeId(2,parentName.substring(0,parentName.length()-1)));
        }
        //同步keepServer通道 、设备 、标识组、标识
        List<? extends UaNode> uaNodes = OpcUaConfig.browseNode(uaNode);
        List<TbEquipment> tbEquipments = new ArrayList<>();
        for ( UaNode t : uaNodes) {
            TbEquipment tbEquipment = new TbEquipment();
            tbEquipment.setEquipmentParent(ObjectUtil.isNull(uaNode)? 0:uaNode.getId());
            tbEquipment.setEquipmentName(t.getBrowseName().getName());
            tbEquipment.setUpdateTime(new Date());
            try {
                if(!ObjectUtil.isNull(uaNode)){
                    if(t instanceof BaseVariableTypeNode){
                        tbEquipment.setDescription(OpcUaConfig.readNode(parentName+tbEquipment.getEquipmentName()
                                +"._Description").toString());
                        tbEquipment.setDbInfo(OpcUaConfig.readNode(parentName+tbEquipment.getEquipmentName()
                                +"._Address").toString());
                    }else {
                        tbEquipment.setDescription(OpcUaConfig.readNode(parentName+tbEquipment.getEquipmentName()
                                +"._System._Description").toString());
                    }

                }else {
                    tbEquipment.setDescription(OpcUaConfig.readNode(tbEquipment.getEquipmentName()
                            +"._System._Description").toString());
                }
            }catch (Exception e){

            }
            //判断类型 如果是FolderType则类型为需要进一步，否则就是具体标识点
            if(t instanceof FolderTypeNode){
                //前端控制 不传uaNode就是同步通道，否则判断是否是同步的标签组否则就是设备
                tbEquipment.setEquipmentType(ObjectUtil.isNull(uaNode)? EquipmentTypeEnum.ONE.getType() :
                        EquipmentTypeEnum.TWO.getType()==uaNode.getEquipmentType()?
                                EquipmentTypeEnum.THREE.getType():EquipmentTypeEnum.TWO.getType());
            }else {
                tbEquipment.setEquipmentType(EquipmentTypeEnum.FOUR.getType());
            }
            tbEquipments.add(tbEquipment);
        }
        //数据库层面
        QueryWrapper<TbEquipment> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("equipment_parent",ObjectUtil.isNull(uaNode)?0:uaNode.getId());
        List<TbEquipment> olds= this.list(queryWrapper);
        List<Long> ids = new ArrayList<>();
        for (TbEquipment old : olds) {
            Optional<TbEquipment> first = tbEquipments.stream().filter(t -> t.getEquipmentName().equals(old.getEquipmentName())
                    && t.getEquipmentType().equals(old.getEquipmentType())).findFirst();
            //需要删除的信息
            if(!first.isPresent()){
                ids.add(old.getId());
            }else {
                tbEquipments.get(tbEquipments.indexOf(first.get())).setId(old.getId());
            }
        }
        if(ids.size()>0){
            this.removeByIds(ids);
        }
        this.saveOrUpdateBatch(tbEquipments);
        return true;
    }


    //查询上级
    private String getParentName(Long id,String name){
        TbEquipment byId = this.getById(id);
        name = byId.getEquipmentName()+".";
        if(byId.getEquipmentParent() != 0){
            name = getParentName(byId.getEquipmentParent(),name)+name;
        }
        return name;
    }
}
